﻿#define DEBUG

using System;
using System.Collections.Generic;
using System.Text;

using System.Collections;
using System.Runtime.InteropServices;

using SuperMapLib;

namespace JR_RouteAlarm.MakingBuffer
{
    class SoubuFastNDHo : Common, IRoute 
    {
        public SoubuFastNDHo(soDatasets objDSs, Hashtable routeLnWithBfr, soStrings objStrFields)
            : base(objDSs, routeLnWithBfr, objStrFields)
        {
        }

        #region IRoute メンバ

        /// <summary>
        /// 総武快速と本線より、バッファーを作成
        /// </summary>
        /// <param name="objVector">処理元の線路データセットベクトル</param>
        public override void MakeBufferForRoute(soDatasetVector objVector)
        {
            soRecordset objRS = null;
            soRecordset objSubRS = null;

            /*該当する処理対象を見当たる*/
            objRS = objVector.Query(
                RouteDataset.FLD_DAIBUN_CD + " = '01' and (" +
                //総武本線
                "(" + RouteDataset.FLD_FEATURE_CD + " = '0102' and " +
                RouteDataset.FLD_TSUUSHO_CD + " = '650')" +
                " or " +
                //総武快速線
                "(" + RouteDataset.FLD_FEATURE_CD + " = '0103' and " +
                RouteDataset.FLD_TSUUSHO_CD + " = '662')" +
                ")",
                false, objStrFields,
                String.Format("group by {0}, {1}, {2} order by {0} desc",
                    RouteDataset.FLD_FEATURE_CD, RouteDataset.FLD_DAIBUN_CD, RouteDataset.FLD_TSUUSHO_CD));
            if (objRS != null && objRS.RecordCount > 0)
            {
                if (!objRS.IsBOF())
                {
                    objRS.MoveFirst();
                }
#if DEBUG
                soGeoLine objFullRoute = null;
                soDatasetVector objDSVKirotei = objDSs["キロ標_千葉"] as soDatasetVector;
                for (int j = 0; j < objRS.RecordCount; objRS.MoveNext(), j++)
#else
                for (; !objRS.IsEOF(); objRS.MoveNext())
#endif
                {
                    try
                    {
                        feature = objRS.GetFieldValue(RouteDataset.FLD_FEATURE_CD).ToString();
                        daibun = objRS.GetFieldValue(RouteDataset.FLD_DAIBUN_CD).ToString();
                        tsuusho = objRS.GetFieldValue(RouteDataset.FLD_TSUUSHO_CD).ToString();

                        Console.WriteLine(
                            String.Format("{0}:{1},\t{2}:{3},\t{4}:{5}\t---{6}/{7}",
                                RouteDataset.FLD_FEATURE_CD, feature,
                                RouteDataset.FLD_DAIBUN_CD, daibun,
                                RouteDataset.FLD_TSUUSHO_CD, tsuusho,
                                j + 1, objRS.RecordCount));

                        objSubRS = objVector.Query(
                            RouteDataset.FLD_FEATURE_CD + " = '" + feature + "' and " +
                            RouteDataset.FLD_DAIBUN_CD + " = '" + daibun + "' and " +
                            RouteDataset.FLD_TSUUSHO_CD + " = '" + tsuusho + "'",
                            true, null, "");

                        int multiLineCount = objSubRS.RecordCount;
                        if (objSubRS != null && multiLineCount > 0)
                        {
                            if (!objSubRS.IsBOF())
                            {
                                objSubRS.MoveFirst();
                            }

                            /*線路はキロ程を通じたら、キロ程データセットベクトルを保留*/
                            soGeoLine objLineTmp = null;
                            int i = 0;
                            Hashtable lineLenWithLine = new Hashtable();
                            for (; !objSubRS.IsEOF(); objSubRS.MoveNext())
                            {
                                objLineTmp = objSubRS.GetGeometry() as soGeoLine;
                                soRecordset objRSContain =
                                    objDSVKirotei.QueryEx(objSubRS.GetGeometry(), seSpatialQueryMode.scsCommonPoint, "");
                                if (objRSContain != null)
                                {
                                    lineLenWithLine[objLineTmp.Length] = objLineTmp;
                                    Marshal.ReleaseComObject(objRSContain);
                                    objRSContain = null;
                                    i++;
                                    Console.WriteLine(objDSVKirotei.Name + "\t\t---\t" + i.ToString() +
                                        "\t---\t" + objLineTmp.Length.ToString());
                                }
                            }
                            objSubRS.Close();
                            Marshal.ReleaseComObject(objSubRS);
                            objSubRS = null;

                            Array lengths = Array.CreateInstance(typeof(Double), i);
                            lineLenWithLine.Keys.CopyTo(lengths, 0);
                            Array.Sort(lengths);
                            Console.WriteLine("max:\t" + lengths.GetValue(i - 1).ToString());
                            if (objFullRoute == null)
                            {
                                objFullRoute = lineLenWithLine[lengths.GetValue(i - 1)] as soGeoLine;
                            }
                            else
                            {
                                objLineTmp = lineLenWithLine[lengths.GetValue(i - 1)] as soGeoLine;
                                //Console.WriteLine("総武本線：" + objFullRoute.Length.ToString());
                                //Console.WriteLine("総武快速線：" + objLineTmp.Length.ToString());
                                //Console.WriteLine("xFull:{0}, yFull:{1}, xTmp:{2}, yTmp:{3}",
                                //    objFullRoute.FindPointOnLineByDistance(objFullRoute.Length).x,
                                //    objFullRoute.FindPointOnLineByDistance(objFullRoute.Length).y,
                                //    objLineTmp.FindPointOnLineByDistance(0).x,
                                //    objLineTmp.FindPointOnLineByDistance(0).y);
                                //soGeoPoint objPointTmp = new soGeoPoint();
                                //objPointTmp.x = objLineTmp.FindPointOnLineByDistance(0).x;
                                //objPointTmp.y = objLineTmp.FindPointOnLineByDistance(0).y;
                                //Console.WriteLine(objFullRoute.DistanceTo(objPointTmp as soGeometry).ToString());

                                soPoints tmpPoints = new soPoints();
                                soGeoLine objLineJoiner = new soGeoLine();
                                tmpPoints.Add(objFullRoute.FindPointOnLineByDistance(objFullRoute.Length));
                                tmpPoints.Add(objLineTmp.FindPointOnLineByDistance(0));
                                objLineJoiner.AddPart(tmpPoints);
                                //Console.WriteLine("本・快速の連結線：" + objLineJoiner.Length.ToString());
                                if (objFullRoute.Joint(objLineJoiner))
                                {
                                    if (objFullRoute.Joint(objLineTmp))
                                    {
                                        Console.WriteLine("joint success!\t" + objFullRoute.Length.ToString());
                                    }
                                }

                                Marshal.ReleaseComObject(objLineTmp);
                                objLineTmp = null;
                                Marshal.ReleaseComObject(objLineJoiner);
                                objLineJoiner = null;
                                Marshal.ReleaseComObject(tmpPoints);
                                tmpPoints = null;
                            }
                        }
                    }
                    catch (System.Threading.ThreadAbortException ae)
                    {
                        throw ae;
                    }
                    catch (Exception ex)
                    {
                        if (objSubRS != null)
                        {
                            objSubRS.Close();
                            Marshal.ReleaseComObject(objSubRS);
                            objSubRS = null;
                        }
                        objRS.Close();
                        Marshal.ReleaseComObject(objRS);
                        objRS = null;

                        throw new Exception(ex.Message);
                    }
                }

                MakeBufferForPart(objFullRoute, objDSVKirotei, null);

                objRS.Close();
                Marshal.ReleaseComObject(objRS);
                objRS = null;
            }

            if (objRS != null)
            {
                objRS.Close();
                Marshal.ReleaseComObject(objRS);
                objRS = null;
            }
        }

        #endregion
    }
}
